﻿using System;
using System.Collections.Generic;

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;

using zijian666.WebApi.Middleware;


namespace zijian666.WebApi
{
    public partial class WebApiOptions
    {

        /// <summary>
        /// 启用返回值标准化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public void EnableResultStandardized<T>()
            where T : class, IResultFormatter
        {
            _services.TryAddSingleton<FormatResultFilter>();
            _services.TryAddSingleton<T>();
            _services.TryAddSingleton<IResultFormatter>(p => p.GetRequiredService<T>());
            _services.Configure<MvcOptions>(x => x.Filters.AddService<FormatResultFilter>());
        }


        /// <summary>
        /// 启用返回值标准化
        /// </summary>
        public void EnableResultStandardized() => EnableResultStandardized<DefaultResult.Formatter>();
    }

    /// <summary>
    /// 默认无数据返回值
    /// </summary>
    public partial class DefaultResult
    {
        /// <summary>
        /// 默认构造函数
        /// </summary>
        /// <param name="requestId">请求id</param>
        public DefaultResult(string requestId) => RequestId = requestId ?? throw new ArgumentNullException(nameof(requestId));
        /// <summary>
        /// 返回值版本
        /// </summary>
        public virtual string Ver { get; } = "Default";
        /// <summary>
        /// 返回编码
        /// </summary>
        public int Code { get; internal protected set; } = 200;
        /// <summary>
        /// 返回子码
        /// </summary>
        public string Subcode { get; internal protected set; } = "ok";
        /// <summary>
        /// 返回消息
        /// </summary>
        public string? Message { get; internal protected set; }

        /// <summary>
        /// 拓展属性
        /// </summary>
        public IDictionary<string, object>? Extra { get; internal protected set; }
        /// <summary>
        /// 请求Id
        /// </summary>
        public string RequestId { get; init; }
        /// <summary>
        /// 异常
        /// </summary>
        public IList<ExceptionInfo>? Exceptions { get; internal protected set; }
        /// <summary>
        /// 异常信息
        /// </summary>
        public record ExceptionInfo(string Message, string StackTrace);
    }

    /// <summary>
    /// 泛型返回值
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class DefaultResult<T> : DefaultResult
    {
        /// <inheritdoc/>
        public DefaultResult(string requestId) : base(requestId)
        {
        }
        /// <summary>
        /// 返回数据
        /// </summary>
        public T? Data { get; internal protected set; }
    }
}
